package sfms.controller;

import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import java.sql.Time;
import java.sql.Timestamp;
import java.util.ArrayList;
import java.util.Collection;
import java.util.List;
import java.util.TreeSet;
import javax.swing.JOptionPane;
import javax.swing.table.DefaultTableModel;
import sfms.model.Booking;
import sfms.model.Facility;
import sfms.model.User;
import sfms.model.Venue;
import sfms.util.CustomDate;
import sfms.util.MD5;
import sfms.view.CreateFacility;
import sfms.view.EditFacility;
import sfms.view.EditUser;

public class Staff implements ControllerBase
{
    private sfms.view.Staff view;
    private sfms.model.Model model;
    private List<sfms.model.User> users;
    private sfms.model.User user;
    
    private DefaultTableModel modelBooking;
    private DefaultTableModel modelUsers;
    private DefaultTableModel modelFacilities;
    private DefaultTableModel modelVenue;

    public void setModelBooking(DefaultTableModel modelBooking) {
        this.modelBooking = modelBooking;
    }

    public void setModelUsers(DefaultTableModel modelUsers) {
        this.modelUsers = modelUsers;
    }
    
    
    public void setModelFacilities(DefaultTableModel modelFacilities) {
        this.modelFacilities = modelFacilities;
    }
    
    public void setModelVenue(DefaultTableModel modelVenue){
        this.modelVenue = modelVenue;
    }
    
    public void refreshVenueTable(int facilityId){
        int count = this.modelVenue.getRowCount();
        for (int i = 0; i < count; i++){
            this.modelVenue.removeRow(0);
        }
        
        System.out.println(facilityId);
        
        for(Venue v : model.getVenues(facilityId)){
            Object [] data = new Object[]{
                v.getId(),
                v.getTitle(),
                v.getCapacity()
            };
            System.out.println(v.getId()+"-"+
                v.getTitle()+"-"+
                v.getCapacity());
            this.modelVenue.insertRow(0, data);
        }
    }
    
    
    public List<Facility> getFacilities(CustomDate item){
        return model.getActiveFacilities(item);
    }
    
    public List<Time> getSlots(Facility item, CustomDate day){
        return model.getAvailableSlots(item, day, true);
        
    }
    
    public List<Venue> getVenues(Facility f){
        List<Venue> v = model.getAvailableVenues(f.getId());
        v = new ArrayList<Venue>(new TreeSet<Venue>((Collection<Venue>) v));
        return v;
        
    }
    
    /**
     * Book an activity.
     */
    public void bookActivity(int venue_id, Time t, java.sql.Date d) {
        Timestamp datetime = new Timestamp(d.getYear(), d.getMonth(), d.getDate(), 
            t.getHours(), t.getMinutes(), 0, 0);
        
        String password = sfms.view.Password.getPassword();
        if (password == null){
            return;
        }
        
        if (model.getUser(user.getUsername(), sfms.util.MD5.encrypt(password.toCharArray())) == null){
            JOptionPane.showMessageDialog(null, "Incorrect Password.");
            return;
        }
        
        if (model.addBooking(user.getUsername(), venue_id, datetime)){
            JOptionPane.showMessageDialog(null, "Booking has been made successfully.");
            view.setActivityOptions(0);
        }
        else{
            JOptionPane.showMessageDialog(null, "There was an error completing your booking.");
        }
        
    }
    
    public void setBookings(java.util.Date d){
        List<Booking> list = model.getBookings(new java.sql.Date(d.getTime()));
        int count = modelBooking.getRowCount();
        for(int i = 0; i < count; i++){
            modelBooking.removeRow(0);
        }
        
        for(Booking b : list){
            Object [] data = new Object[]{
                    b.getVenue().getFacility().getTitle(),
                    new CustomDate(b.getTime()).showTime(),
                    b.getVenue().getTitle()
                };
            modelBooking.addRow(data);
        }
        
    }
    
    public void editFacility(int rownum){
        
        int facilityId = (Integer) modelFacilities.getValueAt(rownum, 0);
        Facility f = model.getFacility(facilityId);
        
        EditFacility ef = new EditFacility(view, true, model, f, this);
    }
    
    public final void refreshFacilityTable(){
        
        int count = this.modelFacilities.getRowCount();
        
        for (int i = 0; i < count ; i++){
            this.modelFacilities.removeRow(0);
        }
        
        List<Facility> list = this.model.getFacilities();
        
        for(Facility f : list){
            String text = "Disabled";
            java.util.Date date = new java.util.Date();
            System.out.println(f.getNotActive());
            System.out.println(f.getNotActive());
            if (f.getNotActive() == null){
                text = "Active";
            }
            else if (f.getNotActive().compareTo(date) > 0){
                CustomDate cDate = new CustomDate();
                cDate.setDate(date.getDate()+7);
                text = "Disabling on " + cDate;
            }
            
            
            Object [] data = new Object[]{
                f.getId(),
                f.getTitle(),
                text
            };
            
            this.modelFacilities.addRow(data);
        }
    }
    
    public final void refreshUserTable(){
        
        int count = this.modelUsers.getRowCount();
        
        for (int i = 0; i < count ; i++){
            this.modelUsers.removeRow(0);
        }
        
        List<User> list = this.model.getUsers(User.CUSTOMER);
        
        for(User u : list){
            
            Object [] data = new Object[] {
                    u.getUsername(),
                    u.getFirstName(),
                    u.getLastName(),
                    u.getExpiry(),
                    u.getEmail(),
                    u.getPhoneNumber(),
                    u.isActive()
                };
            
            this.modelUsers.addRow(data);
        }
    }
    
    
    /**
     * Initialise a new Staff object.
     */
    public Staff(sfms.model.Model model, sfms.model.User currentUser) {
        this.model = model;
        view = new sfms.view.Staff(this);
        this.user = currentUser;
        getUsers();
        refreshFacilityTable();
    }

    @Override
    public void show() {
        view.setVisible(true);
    }
    
    @Override
    public void hide() {
        view.setVisible(false);
        view.dispose();
    }
    
    /**
     * Reserve a venue/facility
     */
    public void reserve() {
    }
    
    /**
     * Get all bookings and reservations
     */
    public void getBookings() {
        
    }
    
    /**
     * Create a new facility
     */
    public void createFacility() {
        //Venue venue = new Venue();
        //model.addVenue(venue);
        CreateFacility cf = new CreateFacility(view, true, this);
    }
    
    public void createFacility(String title, String license, boolean hasLicense){
        Facility f = null;
        
        if (hasLicense){
            f = model.addFacility(title, license);
        }
        else{
            f = model.addFacility(title, null);
        }
    }
    
    public void deleteVenue(int id){
        model.removeVenue(id);
        refreshFacilityTable();
    }
    
    /**
     * Create a new user
     */
    public void createUser(String username,
            String fname, String sname,
            String role, boolean active, String number,
            String email, java.sql.Date expiry,
            String password)
    {
        sfms.model.User user = new sfms.model.User(username, fname, sname, 
                email, number, role, active, 
                expiry, String.valueOf(MD5.encrypt(password.toCharArray())));
        model.addUser(user);
    }
    
    /**
     * Edit/delete a user
     */
    public void editUser(boolean isDeleting, String username)
    {
        if (isDeleting)
        {
            // delete user from// update user information database
        }
        else {
            sfms.model.User selectedUser = model.getUser(username);
            
            EditUser editUser = new EditUser(view, true, this, selectedUser);
            editUser.setVisible(true);
        }
    }
    
    /**
     * Get a list of users for display
     */
    public final void getUsers()
    {
        try{
        users = new ArrayList<User>();
        users.addAll(model.getUsers(User.CUSTOMER));
        }
        catch(Exception e){}
    }
    
    /**
     * Log out of the application
     */
    public void logout() {
        sfms.controller.Login login = new sfms.controller.Login(model);
        this.hide();
        login.show();
    }

    public void addUsers() {
        //First remove rows that may be already there.
        int count = modelUsers.getRowCount();
        for (int i = 0; i < count; i++) {
            modelUsers.removeRow(0);
        }

        users = new ArrayList<User>();
        List<User> customers = model.getUsers(User.CUSTOMER);
        if (customers != null) {
            users.addAll(customers);
        }
        
        if (users != null) {
            for (User u : users) {                
                Object [] data = new Object[] {
                    u.getUsername(),
                    u.getFirstName(),
                    u.getLastName(),
                    u.getExpiry(),
                    u.getEmail(),
                    u.getPhoneNumber(),
                    u.isActive()
                };
                
                modelUsers.addRow(data);
            }
        }
    }
    
    public void updateUser(User user) {
        model.updateUser(user);
    }
    
    public boolean changePassword(String password) { 
        return model.changeUserPassword(user.getUsername(), user.getPassword(), MD5.encrypt(password.toCharArray()));
    }

    public ActionListener getDeleteUserListener() {
        return new ActionListener(){
            @Override
            public void actionPerformed(ActionEvent ae) {
                try{
                    int userRow = view.getUserRow();
                    String username = (String) modelUsers.getValueAt(userRow, 0);
                    
                    String retval = sfms.view.Password.getPassword();
                    System.out.println(retval);
                    
                    String password = sfms.util.MD5.encrypt(retval.toCharArray());
                    System.out.println(password);
                    
                    
                    if (model.getUser(user.getUsername(), password) != null){
                        //Password was good
                        if (model.removeUser(username)){
                            JOptionPane.showMessageDialog(null, "User deleted.",
                                    "Success", JOptionPane.DEFAULT_OPTION);
                            modelUsers.removeRow(userRow);
                        }
                        else{
                            JOptionPane.showMessageDialog(null, "There was an error deleting the user.",
                                    "Error", JOptionPane.DEFAULT_OPTION);
                        }
                    }
                    else{
                        JOptionPane.showMessageDialog(null, "Password incorrect: no changes made.",
                                "Error", JOptionPane.DEFAULT_OPTION);
                    }                    
                }
                catch (ArrayIndexOutOfBoundsException e){
                    System.out.println("No row selected.");
                }
            }
            
        };
    }
}
